今天終於要真的把 Discord BOT 部屬上去了!
如果去掉 Replit,我覺得 Render 的部屬步驟最簡單,所以擺在第一個介紹,GCP 等明天再繼續介紹。
大家也可以參考我去年的去年鐵人賽的文章 XD
Render 是一個提供專門部屬服務的平台,基本上使用者只要準備好程式碼,並設定一下環境變數與啟動指令,就可以輕鬆地部屬自己的服務了。除此之外,一旦 Github 上的程式碼有更新,就會自動觸發重新部屬,不用再自己寫 Github Actions 等 CI/CD 的設定,非常的方便。
昨天有提到,免費額度與條件很重要,所以這此先說明一下 Render 的規定。
Web services 每個月有 750 小時的免費額度 (官方說明),換句話說,如果只有一個服務,那就絕對不會超過額度,可以安心地把它當作一個免費平台使用。
就算不小心超過 (假如同時有多個服務上線的話),這些服務也只會先暫停,不會立刻向使用者收費,如果使用者想要在這個月繼續啟動服務才需要額外付費。
另外,在 Pricing 頁面中的 Compute pricing 也有列出 Web Service 的價格與規格:
在此以 Replit 上的公開專案為例,在 Github 上準備以下三個檔案:
main.py
:Discord BOT 主程式keep_alive.py
:簡單的後端 serverrequirements.txt
:Python 套件清單 (部屬時需要)# main.py
import os
import discord
from keep_alive import keep_alive
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
try:
token = os.getenv("TOKEN") or ""
if token == "":
raise Exception("Please add your token to the Secrets pane.")
keep_alive()
client.run(token)
except discord.HTTPException as e:
if e.status == 429:
print(
"The Discord servers denied the connection for making too many requests"
)
print(
"Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
)
else:
raise e
# keep_alive.py
from flask import Flask
from threading import Thread
app = Flask('')
@app.route('/')
def main():
return '<h1>Bot is awake</h1>'
def run():
app.run(host="0.0.0.0", port=8080)
def keep_alive():
server = Thread(target=run)
server.start()
# requirements.txt
discord.py
flask
想特別提一下,在 main.py
中是使用 os.getenv("TOKEN")
來取得 Discord BOT 的 Token,這樣就可以避免把 Token 上傳到 Github 上。
準備好程式碼後,就可以來設定 Render 了。
點擊「+ New」按鈕,選擇 Web Service。
選擇後,點擊右下的「Connect」按鈕。
如果是第一次使用 Render,則需要先授與 Github 的權限給 Render,才會看到 Repository 的選項。
接下來會看到很多設定,大部分都不用改,但是啟動指令要自己設定。
python main.py
要記得修改方案,選擇 Free 的那一個。
最後就是設定環境變數,把 Discord BOT 的 Token 加上去,這樣啟動時才能讀取到 Token。
最後,點擊最下面的「Deploy Web Service」按鈕,開始部屬。
接著就會看到部屬時的 Log
如果有看到 discord.py
的 Log 訊息,以及 Flask 啟動成功的 Log 訊息 (Running on http://127.0.0.1:8080
),就代表啟動成功了。
此時可以看到 Discord BOT 上線了,也可以對指令有回應。
光是上面那樣還不夠,我們還需要使用 UptimeRobot 來確保這個 Web Service 不會休眠。
設定之前,要先確認一下部屬的網址,網址會在標題的下方:
預設會是 名稱 + .onrender.com
點進去就會看到自己設定的畫面:
UptimeRobot 的設定步驟非常簡單。步驟如下:
進入 UptimeRobot 後,點擊右上的「+ New monitor」按鈕。
填寫先前在 Render 所看到的 Web Service 的 URL。時間間隔就維持預設的 5 分鐘一次即可。(更短的話要付費才有)
設定完成後,點擊左下的「Create monitor」按鈕,就完成啦!
一開始,我有嘗試過不額外開啟新的 thread 去執行後端 server,單純只是執行 Discord BOT 主程式。結果是:剛部屬完成時,Discord BOT 可以正常運作,但隨後 Render 檢查發現沒有設定對外的 Port (後端 server 一定會有),所以就自行把這個程式關閉了。
所以,在 Render 部屬 Discord BOT 時,另外在一個 thread 上執行後端 server 是必要的手段。
今天介紹了如何部屬 Discord BOT 在 Render 上,並搭配 UptimeRobot 來確保 Discord BOT 不會下線。